package com.cocotingo.lab.snail.previewer;


import java.awt.Frame;
import java.awt.Panel;
import java.util.ArrayList;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.awt.SWT_AWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import org.w3c.dom.Element;

import com.cocotingo.snail.template.previewer.TemplatePreviewerView;


/**
 * This sample class demonstrates how to plug-in a new
 * workbench view. The view shows data obtained from the
 * model. The sample creates a dummy model on the fly,
 * but a real implementation would connect to the model
 * available either in this or another plug-in (e.g. the workspace).
 * The view is connected to the model using a content provider.
 * <p>
 * The view uses a label provider to define how model
 * objects should be presented in the view. Each
 * view can present the same model objects using
 * different labels and icons, if needed. Alternatively,
 * a single label provider can be shared between views
 * in order to ensure that objects of the same type are
 * presented in the same way everywhere.
 * <p>
 */

public class PreviewerView extends ViewPart implements ISelectionListener {

	/**
	 * The ID of the view as specified by the extension.
	 */
	public static final String ID = "com.cocotingo.lab.snail.previewer.PreviewerView";

	
	private TableViewer viewer;
	private Context context;
	
	/*
	 * The content provider class is responsible for
	 * providing objects to the view. It can wrap
	 * existing objects in adapters or simply return
	 * objects as-is. These objects may be sensitive
	 * to the current input of the view, or ignore
	 * it and always show the same content 
	 * (like Task List, for example).
	 */
	 
	class ViewContentProvider implements IStructuredContentProvider {
		TemplatePreviewerView view;
		ViewContentProvider(TemplatePreviewerView view) {
			this.view = view;
		}
		public void inputChanged(Viewer v, Object oldInput, Object newInput) {
		}
		public void dispose() {
		}
		public Object[] getElements(Object parent) {
			if (view == null) return new Object[0];
			else {
				ArrayList<String> rst = new ArrayList<String>();
				for (Map.Entry<String, String> pair : view.getAllAttributes()) {
					rst.add(String.format("%s = \"%s\"", pair.getKey(), pair.getValue()));
				}
				return rst.toArray();
			}
		}
	}
	class ViewLabelProvider extends LabelProvider implements ITableLabelProvider {
		public String getColumnText(Object obj, int index) {
			return getText(obj);
		}
		public Image getColumnImage(Object obj, int index) {
			return getImage(obj);
		}
		public Image getImage(Object obj) {
			return PlatformUI.getWorkbench().
					getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT);
		}
	}
	class NameSorter extends ViewerSorter {
	}

	/**
	 * The constructor.
	 */
	public PreviewerView() {
	}

	/**
	 * This is a callback that will allow us
	 * to create the viewer and initialize it.
	 */
	public void createPartControl(Composite parent) {
		getSite().getWorkbenchWindow().getSelectionService().addSelectionListener(this);
		
		Composite composite = new Composite(parent, SWT.EMBEDDED | SWT.DOUBLE_BUFFERED | SWT.NO_REDRAW_RESIZE | SWT.NO_BACKGROUND);
		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		Frame bridge = SWT_AWT.new_Frame(composite);
		Panel panel = new Panel();
		bridge.add(panel);
		context = new Context(panel, this);
		
		viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
		viewer.setContentProvider(new ViewContentProvider(null));
		viewer.setLabelProvider(new ViewLabelProvider());
		viewer.setSorter(new NameSorter());
		viewer.setInput(getViewSite());
		
		GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
		data.heightHint = 100;
		viewer.getControl().setLayoutData(data);
		
		GridLayout layout = new GridLayout();
		layout.numColumns = 1;
		parent.setLayout(layout);
	}
	
	@Override
	public void dispose() {
		context.dispose();
		context = null;
		getSite().getWorkbenchWindow().getSelectionService().removeSelectionListener(this);
		super.dispose();
	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		viewer.getControl().setFocus();
	}
	
	private IFile xmlFile = null;
	private String templateID = null;

	@Override
	public void selectionChanged(IWorkbenchPart part, ISelection selection) {
		if (selection instanceof ITreeSelection) {
			ITreeSelection tree = (ITreeSelection) selection;
			if (tree.getFirstElement() instanceof IFile) {
				IFile file = (IFile) tree.getFirstElement();
				if (file.getFileExtension().equals("xml")) {
					if (!file.equals(xmlFile)) {
						xmlFile = file;
						xmlFileChanged();
					}
				}
			} else if (tree.getFirstElement() instanceof Element) {
				Element el = (Element) tree.getFirstElement();
				if (el.getNodeName().equals("Template")) {
					String id = el.getAttribute("id");
					if (id != null && !id.isEmpty() && !id.equals(templateID)) {
						templateID = id;
						templateIDChanged();
					}
				}
			}
		}
	}
	
	private void xmlFileChanged() {
		context.displayTemplate(xmlFile);
	}
	
	private void templateIDChanged() {
		if (xmlFile != null) {
			context.displayTemplate(templateID);
		}
	}
	
	public void showDetailOfView(final TemplatePreviewerView view) {
		viewer.getControl().getDisplay().asyncExec(new Runnable() {
			@Override
			public void run() {
				viewer.setContentProvider(new ViewContentProvider(view));
				viewer.setLabelProvider(new ViewLabelProvider());
				viewer.setSorter(new NameSorter());
				viewer.setInput(getViewSite());
			}
		});
		
	}
	
}